package edu.pku.sei.modeler.uml.commands.timing;

import org.eclipse.draw2d.AbsoluteBendpoint;
import org.eclipse.draw2d.Bendpoint;
import org.eclipse.gef.commands.Command;

import edu.pku.sei.modeler.editpolicies.TimeLineBendPointPolicy;
import edu.pku.sei.modeler.exceptions.FactoryNotFoundException;
import edu.pku.sei.modeler.model.common.AbstractFactory;
import edu.pku.sei.modeler.model.common.ModelRegistry;
import edu.pku.sei.modeler.model.structure.MetaBendPoint;
import edu.pku.sei.modeler.model.structure.MetaLink;
import edu.pku.sei.modeler.model.structure.StructureFactory;

public class TimeLineDeleteBendPointCommand extends Command {
	MetaLink link;
	int index;
	byte deleteMark;
	StructureFactory sFactory;
	MetaBendPoint left3, left2, left1, right1, right2, right3;
	public TimeLineDeleteBendPointCommand(MetaLink model, int index,
			byte deleteMark) {
		this.link = model;
		this.index = index;
		this.deleteMark = deleteMark;
		try {
			sFactory = (StructureFactory)ModelRegistry.getRegistry().getStructureFactory(link.getModelElement().getModel());
		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (FactoryNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		if (index >= 3)
			left3 = (MetaBendPoint) link.getBendPoints().get(index - 3);
		if (index >= 2)
			left2 = (MetaBendPoint) link.getBendPoints().get(index - 2);
		if (index >= 1)
			left1 = (MetaBendPoint) link.getBendPoints().get(index - 1);
		int size = link.getBendPoints().size();
		if (size - index >= 3) {
			right3 = (MetaBendPoint) link.getBendPoints().get(index + 2);
		}
		if (size - index >= 2) {
			right2 = (MetaBendPoint) link.getBendPoints().get(index + 1);
		}
		if (size - index >= 1) {
			right1 = (MetaBendPoint) link.getBendPoints().get(index);
		}
	}
	@Override
	public boolean canExecute() {
		return true;
	}
	
	@Override
	public void execute() {
		if ((deleteMark & TimeLineBendPointPolicy.HORIZONTAL_MOVE_DELETE_RIGHT2_POINTS) != 0) {
			deleteHorizontalRight2Points(index);
		}
		if ((this.deleteMark & TimeLineBendPointPolicy.HORIZONTAL_MOVE_DELETE_LEFT2_POINTS) != 0){
			deleteHorizontalLeft2Points(index);
		}
		if ((this.deleteMark & TimeLineBendPointPolicy.VERTICAL_MOVE_DELETE_LEFT2_POINTS) != 0) {
			deleteVerticalLeft2Points(index);	
			
			if ((this.deleteMark & TimeLineBendPointPolicy.VERTICAL_MOVE_DELETE_OUTER_LEFT_RIGHT_POINTS) != 0) {
				deleteVerticalOuter2Points(index-2);
			}
		}
		
		if ((this.deleteMark & TimeLineBendPointPolicy.VERTICAL_MOVE_DELETE_RIGHT2_POINTS) != 0) {
			deleteVerticalRight2Points(index);
			
			if ((this.deleteMark & TimeLineBendPointPolicy.VERTICAL_MOVE_DELETE_OUTER_LEFT_RIGHT_POINTS) != 0) {
				deleteVerticalOuter2Points(index);
			}
		}
	}
	
	private void deleteHorizontalLeft2Points(int index) {
		if (link.getBendPoints().size() > index) {
			MetaBendPoint newRight1 = sFactory.createMetaBendPoint();
			newRight1.x = ((MetaBendPoint)link.getBendPoints().get(index)).x;
			newRight1.y = ((MetaBendPoint)link.getBendPoints().get(index - 2)).y;
			link.getBendPoints().set(index, newRight1);
		}
		link.getBendPoints().remove(index - 1);
		link.getBendPoints().remove(index - 2);	
	}
	
	private void deleteHorizontalRight2Points(int index) {
		if (index - 1 >= 0) {
			MetaBendPoint newLeft1 = sFactory.createMetaBendPoint();
			newLeft1.x = ((MetaBendPoint)link.getBendPoints().get(index - 1)).x;
			newLeft1.y = ((MetaBendPoint)link.getBendPoints().get(index + 1)).y;
			link.getBendPoints().set(index - 1, newLeft1);
		}
		link.getBendPoints().remove(index + 1);
		link.getBendPoints().remove(index);
	}
	
	private void deleteVerticalRight2Points(int index) {
		if (index > 0) {
			MetaBendPoint newLeft1 = sFactory.createMetaBendPoint();
			newLeft1.x = ((MetaBendPoint)link.getBendPoints().get(index + 1)).x;
			newLeft1.y = ((MetaBendPoint)link.getBendPoints().get(index - 1)).y;
			link.getBendPoints().set(index - 1, newLeft1);
		}
		link.getBendPoints().remove(index + 1);
		link.getBendPoints().remove(index);
	}
	private void deleteVerticalLeft2Points(int index) {
		if (link.getBendPoints().size() > index) {
			MetaBendPoint newRight1 = sFactory.createMetaBendPoint();
			newRight1.x = ((MetaBendPoint)link.getBendPoints().get(index - 2)).x;
			newRight1.y = ((MetaBendPoint)link.getBendPoints().get(index)).y;
			link.getBendPoints().set(index, newRight1);
		}
		link.getBendPoints().remove(index - 1);
		link.getBendPoints().remove(index - 2);	
	}
	private void deleteVerticalLeftRightPoints(int index) {
		link.getBendPoints().remove(index);
		link.getBendPoints().remove(index - 1);
	}
	private void deleteVerticalOuter2Points(int index) {
		if (index >= 2) {
			index = index - 1;
			deleteHorizontalRight2Points(index);
			
		} else if (index <= link.getBendPoints().size() - 2) {
			index = index + 1;
			deleteHorizontalLeft2Points(index);
		}else {
			deleteVerticalLeftRightPoints(index);
		}
	}
}
